home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / fdtopragma / fdtopragma.c < prev   
C/C++ Source or Header  |  1997-09-09  |  10KB  |  449 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. /*
  7.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  8.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  9.  *    DICE-LICENSE.TXT.
  10.  */
  11.  
  12. /*
  13.  *  FDTOPRAGMA.C
  14.  *
  15.  *  FDTOPRAGMA fdfile [-o inline_header_file]
  16.  *  FDTOPRAGMA fddir  [-o inlinedir]
  17.  *
  18.  *  Generates an #include file for inline library calls given an FD file
  19.  *  and CLIB-style prototype file.  The generated header file consists of
  20.  *  entries as follows:
  21.  *
  22.  *  void func1(__A6 void *,__D0 int, __D1 int);
  23.  *  #pragma FubarBase func1 2e 0102
  24.  *  ...
  25.  */
  26.  
  27. #ifdef AMIGA
  28. #include <exec/types.h>
  29. #include <exec/nodes.h>
  30. #include <exec/lists.h>
  31. #include <clib/alib_protos.h>
  32. #include <clib/exec_protos.h>
  33. #include <clib/dos_protos.h>
  34. #include <clib/alib_protos.h>
  35. #include <lib/profile.h>
  36. #include <lib/version.h>
  37. #include <lists.h>
  38. #else
  39. #include <suplib/all.h>
  40. #include <include/lib/profile.h>
  41. #include <include/lib/version.h>
  42. #endif
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <stdarg.h>
  47. #include <fcntl.h>
  48. #include <sys/stat.h>
  49. #include <sys/file.h>
  50. #include <sys/dir.h>
  51. #include <time.h>
  52.  
  53. IDENT("FDTOPRAGMA", ".9");
  54. DCOPYRIGHT;
  55.  
  56. typedef unsigned char  ubyte;
  57. typedef unsigned short uword;
  58. #ifndef linux
  59. typedef unsigned long  ulong;
  60. #endif
  61. typedef struct List    List;
  62. typedef struct Node    Node;
  63.  
  64. typedef struct FDNode {
  65.     Node    fn_Node;
  66.     short   fn_Args;
  67.     long    fn_Offset;        /*    library offset        */
  68.     char    fn_Regs[32];    /*    transfer registers  */
  69. } FDNode;
  70.  
  71. void    help(short);
  72. void    exiterr(const char *, ...);
  73. void    ScanFD(FILE *);
  74. char    *ParseArg(char *, char **);
  75. void    GenerateOutput(FILE *, char *);
  76. void    GenerateFunction(char *, long);
  77. void    GeneratePragmas(char *, char *);
  78.  
  79. List    FDList;     /*  list of FD files   */
  80.  
  81. char    *BaseVar;
  82. char    *BaseVarPtr;
  83.  
  84. char    Buf[256];
  85.  
  86. int _DiceCacheEnable = 1;
  87.  
  88. int
  89. main(int ac, char **av)
  90. {
  91.     short i;
  92.     struct stat s;
  93.     char *fdName = NULL;
  94.     char *outName = NULL;
  95.  
  96.     for (i = 1; i < ac; ++i) {
  97.     char *ptr = av[i];
  98.  
  99.     if (*ptr != '-') {
  100.         if (fdName == NULL)fdName = ptr;
  101.         else help(1);
  102.         continue;
  103.     }
  104.     ptr += 2;
  105.     switch(ptr[-1]) {
  106.     case 'o':
  107.         outName = (*ptr) ? ptr : av[++i];
  108.         break;
  109.     default:
  110.         help(0);
  111.         break;
  112.     }
  113.     }
  114.     if (fdName == NULL)
  115.     help(0);
  116.  
  117.     /*
  118.      *    HACK, handle case where fdName is a directory
  119.      */
  120.     if (stat(fdName, &s) == 0 && (s.st_mode & S_IFDIR)) {
  121.     DIR *dir;
  122.     struct direct *direct;
  123.  
  124.     if ((dir = opendir(fdName)) != NULL) {
  125.         while ((direct = readdir(dir)) != NULL) {
  126.         char *ptr;
  127.  
  128.         if ((ptr = strstr(direct->d_name, "_lib.fd")) != NULL) {
  129.             static char FdPath[256];
  130.             static char OutPath[256];
  131.  
  132.             sprintf(FdPath, "%s%s", fdName, direct->d_name);
  133.             sprintf(OutPath, "%s%.*s_pragmas.h", outName ? outName : "",
  134.                              ptr - direct->d_name, direct->d_name);
  135.             GeneratePragmas(FdPath, OutPath);
  136.         } else {
  137.             fprintf(stderr, "%s: expected '_lib.fd' trailer\n", direct->d_name);
  138.         }
  139.         }
  140.         closedir(dir);
  141.     }
  142.     }
  143.     else {
  144.     GeneratePragmas(fdName, outName);
  145.     }
  146.     return(0);
  147. }
  148.  
  149. void
  150. GeneratePragmas(fdFile, outFile)
  151. char *fdFile;
  152. char *outFile;
  153. {
  154.     NewList(&FDList);
  155.     BaseVarPtr = BaseVar = NULL;
  156.  
  157.     if(outFile)printf("FD=%s OUT=%s\n", fdFile, outFile);
  158.     else printf("FD=%s\n", fdFile);
  159.  
  160.     /*
  161.      *    Generate FD specifications from FD file
  162.      */
  163.  
  164.     {
  165.     FILE *fi;
  166.     if ((fi = fopen(fdFile, "r")) == NULL)
  167.         exiterr("Unable to open .FD file: %s", fdFile);
  168.     ScanFD(fi);
  169.     fclose(fi);
  170.     }
  171.  
  172.     /*
  173.      *    Generate output
  174.      */
  175.  
  176.     if (outFile) {
  177.     FILE *fo;
  178.  
  179.     if ((fo = fopen(outFile, "w")) != NULL) {
  180.         GenerateOutput(fo, outFile);
  181.         fclose(fo);
  182.     } else {
  183.         exiterr("Can't create %s\n", outFile);
  184.     }
  185.     } else {
  186.     GenerateOutput(stdout, outFile);
  187.     }
  188. }
  189.  
  190. void
  191. exiterr(const char *ctl, ...)
  192. {
  193.     va_list va;
  194.  
  195.     va_start(va, ctl);
  196.     vfprintf(stderr, ctl, va);
  197.     va_end(va);
  198.     fprintf(stderr, "\n");
  199.     exit(5);
  200. }
  201.  
  202. void
  203. help(short code)
  204. {
  205.     puts(Ident);
  206.     puts(DCopyright);
  207.     puts("FDTOPRAGMA fdfile [-o outfile]");
  208.     puts("FDTOPRAGMA fddir/ [-o outdir/]");
  209.     puts("  Generates header files for inline library calls");
  210.     exit(code);
  211. }
  212.  
  213. void
  214. ScanFD(fi)
  215. FILE *fi;
  216. {
  217.     long bias = -1;
  218.     short end = 0;
  219.     short public = 1;
  220.  
  221.     char *key;
  222.  
  223.     while (fgets(Buf, sizeof(Buf), fi)) {
  224.     if (Buf[0] == '\n' || Buf[0] == '*')
  225.         continue;
  226.     if (strncmp(Buf, "##", 2) != 0) {
  227.         if (bias < 0 || BaseVar == NULL) {
  228.         if (bias < 0) {
  229.             bias = 30;
  230.             printf("Error, No ##bias before function: %s\n", Buf);
  231.         }
  232.         if (BaseVar == NULL) {
  233.             BaseVarPtr = BaseVar = strdup("UnknownBase");
  234.             printf("Error, No ##base before function: %s\n", Buf);
  235.         }
  236.         }
  237.         if (public)
  238.         GenerateFunction(Buf, bias);
  239.         bias += 6;
  240.         continue;
  241.     }
  242.     if ((key = strtok(Buf + 2, " \t\n")) == NULL) {
  243.         printf("\tError, Illegal null directive\n");
  244.         continue;
  245.     }
  246.     if (stricmp(key, "base") == 0) {
  247.         if ((key = strtok(NULL, " \t\n")) != NULL) {
  248.         if (BaseVar)
  249.             free(BaseVar);
  250.         BaseVarPtr = BaseVar = strdup(key);
  251.         if (BaseVar[0] == '_')
  252.             ++BaseVarPtr;
  253.         } else {
  254.         printf("\tError, Illegal ##base directive\n");
  255.         }
  256.         continue;
  257.     }
  258.     if (stricmp(key, "bias") == 0) {
  259.         if ((key = strtok(NULL, " \t\n")) != NULL) {
  260.         char *dummy;
  261.  
  262.         bias = strtol(key, &dummy, 0);
  263.         if (bias <= 0)
  264.             printf("\tError, Illegal ##bias: %ld\n", bias);
  265.         } else {
  266.         printf("\tError, Illegal ##bias directive\n");
  267.         }
  268.         continue;
  269.     }
  270.     if (stricmp(key, "public") == 0) {
  271.         public = 1;
  272.         continue;
  273.     }
  274.     if (stricmp(key, "private") == 0) {
  275.         public = 0;
  276.         continue;
  277.     }
  278.     if (stricmp(key, "end") == 0) {
  279.         end = 1;
  280.         break;
  281.     }
  282.     printf("\tError, Unrecognized directive: %s\n", key);
  283.     }
  284.     if (bias < 0)
  285.     puts("\tUnexpected EOF, no ##bias");
  286.     if (BaseVar == NULL)
  287.     puts("\tUnexpected EOF, no ##base");
  288.     if (end == 0)
  289.     puts("\tUnexpected EOF, no ##end directive");
  290. }
  291.  
  292. /*
  293.  *  funcname(var,var,var)(reg,reg,reg)        (or reg/reg)
  294.  */
  295.  
  296. void
  297. GenerateFunction(buf, bias)
  298. char *buf;
  299. long bias;
  300. {
  301.     FDNode *fd = malloc(sizeof(FDNode));
  302.     char *scanPtr = buf;
  303.  
  304.     clrmem(fd, sizeof(FDNode));
  305.  
  306.     fd->fn_Offset = bias;
  307.  
  308.     {
  309.     short noArgs = 0;
  310.  
  311.     while (*scanPtr && *scanPtr != '\t' && *scanPtr != ' ' && *scanPtr != '(')
  312.         ++scanPtr;
  313.     if (*scanPtr == ' ' || *scanPtr == '\t') {
  314.         while (*scanPtr && *scanPtr != '(')
  315.         *scanPtr++ = 0;
  316.     }
  317.     if (*scanPtr == '(') {
  318.         *scanPtr++ = 0;
  319.         if (*scanPtr == ')')
  320.         noArgs = 1;
  321.     }
  322.     while (*scanPtr && *scanPtr != ')')   /*  skip text args  */
  323.         ++scanPtr;
  324.     while (*scanPtr && *scanPtr != '(')
  325.         ++scanPtr;
  326.     if (noArgs == 0 && *scanPtr == 0) {
  327.         printf("\tError in line: %s\n", buf);
  328.         return;
  329.     }
  330.     }
  331.     fd->fn_Node.ln_Name = strdup(buf);
  332.  
  333.     /*
  334.      *    get register description
  335.      */
  336.  
  337.     if (*scanPtr)
  338.     ++scanPtr;
  339.  
  340.     for (fd->fn_Args = 0; *scanPtr && *scanPtr != '\n' && *scanPtr != ')'; ++fd->fn_Args) {
  341.     switch(*scanPtr) {
  342.     case 'd':
  343.     case 'D':
  344.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0';
  345.         ++scanPtr;
  346.         break;
  347.     case 'a':
  348.     case 'A':
  349.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0' + 8;
  350.         ++scanPtr;
  351.         break;
  352.     default:
  353.         printf("\tError in register spec: %s\n", scanPtr);
  354.         return;
  355.     }
  356.     if (*scanPtr == ',' || *scanPtr == '/')
  357.         ++scanPtr;
  358.     }
  359.     if (fd->fn_Args == 0 && *scanPtr != ')') {
  360.     printf("\tError in register spec: %s\n", scanPtr);
  361.     return;
  362.     }
  363.     AddTail(&FDList, &fd->fn_Node);
  364. }
  365.  
  366.  
  367. char *
  368. ParseArg(ptr, ppt)
  369. char *ptr;
  370. char **ppt;
  371. {
  372.     char *base = ptr;
  373.  
  374.     if (ptr) {
  375.     while (*ptr && *ptr != '(')
  376.         ++ptr;
  377.     if (*ptr == '(') {
  378.         for (base = ++ptr; *ptr && *ptr != ')'; ++ptr)
  379.         ;
  380.         if (*ptr == ')') {
  381.         *ptr++ = 0;
  382.         *ppt = strdup(base);
  383.         } else {
  384.         ptr = NULL;
  385.         }
  386.     } else {
  387.         ptr = NULL;
  388.     }
  389.     }
  390.     return(ptr);
  391. }
  392.  
  393. void
  394. GenerateOutput(fo, outFile)
  395. FILE *fo;
  396. char *outFile;
  397. {
  398.     FDNode *fd;
  399.  
  400.     /* ** $ VER: proto/diskfont.h 1.0 (17.4.93) **        */
  401.     /* #ifndef DISKFONT_PROTO_H                          */
  402.     /* #define DISKFONT_PROTO_H 1                        */
  403.     /* #include <pragmas/config.h>                       */
  404.     /* #include <exec/types.h>                           */
  405.     /* #include <clib/diskfont_protos.h>                 */
  406.     /* #ifdef __SUPPORTS_PRAGMAS__                       */
  407.     /* extern struct Library *DiskfontBase;              */
  408.     /* #include <pragmas/diskfont_pragmas.h>             */
  409.     /* #endif                                            */
  410.     /* #endif                                            */
  411.  
  412.     {
  413.     time_t t;
  414.     struct tm *tp;
  415.  
  416.     time(&t);
  417.     tp = localtime(&t);
  418.  
  419.     fprintf(fo, "/* %cVER: %s 1.0 (%d.%d.%d) */\n",
  420.                '$',
  421.                outFile ? outFile : "",
  422.                (int)tp->tm_mday, 
  423.                (int)tp->tm_mon, 
  424.                (int)tp->tm_year
  425.         );
  426.     }
  427.  
  428.     fprintf(fo, "#ifndef %s_PRAGMA_H\n", BaseVarPtr);
  429.     fprintf(fo, "#define %s_PRAGMA_H\n\n", BaseVarPtr);
  430.  
  431.     /*
  432.      *    #define's to generate library calls
  433.      */
  434.  
  435.     for (fd = GetHead(&FDList); fd; fd = GetSucc(&fd->fn_Node))
  436.     {
  437.     short i;
  438.  
  439.     fprintf(fo, "#pragma libcall %s %s %lx ", BaseVarPtr,
  440.                 fd->fn_Node.ln_Name, fd->fn_Offset);
  441.  
  442.     for (i = fd->fn_Args - 1; i >= 0; --i)
  443.         fprintf(fo, "%x", fd->fn_Regs[i]);
  444.     fprintf(fo, "0%x\n", fd->fn_Args & 15);
  445.     }
  446.     fprintf(fo, "\n#endif\n");
  447. }
  448.  
  449.